package it.disim.tlp.webreputation.business.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import it.disim.tlp.webreputation.business.AbstractDataAggregatorFactory;
import it.disim.tlp.webreputation.business.FactoryBuilder;
import it.disim.tlp.webreputation.business.SorgenteService;
import it.disim.tlp.webreputation.business.UtenteService;
import it.disim.tlp.webreputation.business.model.Connector;
import it.disim.tlp.webreputation.business.model.Sorgente;
import it.disim.tlp.webreputation.business.model.Utente;

public class JDBCSorgenteService implements SorgenteService {
	
	/**
	 * The method takes all sources (source type ()) of a connector.
	 * @param connector An object of type Connector () "filled" (With inside the id of the connector).
	 * @return Collection<Sorgente> Returns a collection of objects of type Source () that refer to the input connector.
	 */
	@Override
	public Collection<Sorgente> getSorgentiFromConnector(Connector connector) {
		
		Connection con = DBConnect.getConnection();

		AbstractDataAggregatorFactory factory = FactoryBuilder.getInstance();

		Statement st = null;
		ResultSet rs = null;
		Collection<Sorgente> sorgenti = new ArrayList<Sorgente>();

		try {
			st = con.createStatement();

			rs = st.executeQuery("SELECT * FROM sorgenti WHERE Connettore = " + connector.getId());

			while (rs.next()) {

				Sorgente sorgente = new Sorgente();
				sorgente.setId(rs.getInt("ID"));
				sorgente.setName(rs.getString("NomeConnettore"));
				sorgente.setDescription(rs.getString("Descrizione"));
				sorgente.setLink(rs.getString("Link"));
				sorgente.setTipo(rs.getString("Tipo"));
				sorgente.setIcona(rs.getString("Icona"));
				
				//Abbiamo bisogno di un long, ma nel Db c'è int quindi facciamo una conversione esplicita
				long l = ((long)rs.getInt("lastTimestamp")) * 1000;
				sorgente.setLast_timestamp(l);
				
				//sorgente.setLast_timestamp(rs.getInt("lastTimestamp"));

				// We go there to take you through the method author appropriate in UtenteService
				UtenteService utenteService = factory.getUtenteService();
				Utente autore = utenteService.getUser(new Utente(rs.getInt("Autore")));
				sorgente.setAutore(autore);

				sorgente.setConnector(connector);

				sorgenti.add(sorgente);
			}

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return sorgenti;
	}

	
	/**
	 * The method makes the update of the source that is passed as input. Through the id goes to update only that source.
	 * @param sorgente An object of type Source () that needs to be changed.
	 * @return void Returns nothing, it is essentially just the update.
	 */
	@Override
	public void updateSorgente(Sorgente sorgente) {
		
		Connection con = DBConnect.getConnection();	

		Statement st = null;
		try {
			
			String updateTableSQL = "UPDATE sorgenti SET lastTimestamp = ? WHERE ID = ?";
			PreparedStatement preparedStatement = con.prepareStatement(updateTableSQL);
						
			//Abbiamo bisogno di un int ora per salvare correttamente bel DB.
			//Il cast da long a int in questo caso non è distruttivo in quanto facendo prima la divisione per 1000 il valore
			//diventa di 10 cifre e quindi il cast ad int ritorna esattamente le 10 cifre senza tagliare.
			int long_last_timestamp_to_save = (int) (sorgente.getLast_timestamp() / 1000);			

			preparedStatement.setInt(1, long_last_timestamp_to_save);
			preparedStatement.setInt(2, sorgente.getId());
			// execute insert SQL stetement
			preparedStatement .executeUpdate();					
			

		} catch (SQLException e) {
			e.printStackTrace();			
		} finally {
			if (st!=null) {
				try {st.close();} catch (SQLException e) {}			

		}
		
		}

	}
	
	
	public List<Sorgente> getSorgenti() {
		
		Connection con = DBConnect.getConnection();

		AbstractDataAggregatorFactory factory = FactoryBuilder.getInstance();

		Statement st = null;
		ResultSet rs = null;
		List<Sorgente> sorgenti = new ArrayList<Sorgente>();

		try {
			st = con.createStatement();

			rs = st.executeQuery("SELECT * FROM sorgenti");

			while (rs.next()) {

				Sorgente sorgente = new Sorgente();
				sorgente.setId(rs.getInt("ID"));
				sorgente.setName(rs.getString("NomeConnettore"));
				sorgente.setDescription(rs.getString("Descrizione"));
				sorgente.setLink(rs.getString("Link"));
				sorgente.setTipo(rs.getString("Tipo"));
				sorgente.setIcona(rs.getString("Icona"));
				
				//Abbiamo bisogno di un long, ma nel Db c'� int quindi facciamo una conversione esplicita
				long l = ((long)rs.getInt("lastTimestamp")) * 1000;
				sorgente.setLast_timestamp(l);

				// We go there to take you through the method author appropriate in UtenteService
				UtenteService utenteService = factory.getUtenteService();
				Utente autore = utenteService.getUser(new Utente(rs.getInt("Autore")));
				sorgente.setAutore(autore);				

				sorgenti.add(sorgente);
			}

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return sorgenti;
	}


	
}
